#!/usr/bin/env python3
"""
统一的WVP服务模块
Unified WVP Service Module

基于原始 wvp_service.py，提供从Java后端获取真实WVP数据的功能
参考: D:\Projects\MergeTwins30\RuoYi-Wvp-星球版\python-backend\services\wvp_service.py
"""
import asyncio
import aiohttp
import json
import logging
from typing import Dict, List, Any, Optional
from datetime import datetime, timedelta
from enum import Enum

from database.simple_db import get_database_manager

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class PlayFormat(Enum):
    """播放格式枚举"""
    WEBRTC = "webrtc"
    HTTP_FLV = "flv"
    HLS = "hls"
    RTSP = "rtsp"


class CacheManager:
    """缓存管理器"""
    
    def __init__(self, default_ttl: int = 300):  # 5分钟默认TTL
        self.cache = {}
        self.default_ttl = default_ttl
    
    def get(self, key: str) -> Optional[Any]:
        """获取缓存数据"""
        if key in self.cache:
            data, expire_time = self.cache[key]
            if datetime.now() < expire_time:
                return data
            else:
                del self.cache[key]
        return None
    
    def set(self, key: str, value: Any, ttl: Optional[int] = None) -> None:
        """设置缓存数据"""
        ttl = ttl or self.default_ttl
        expire_time = datetime.now() + timedelta(seconds=ttl)
        self.cache[key] = (value, expire_time)
    
    def delete(self, key: str) -> None:
        """删除缓存数据"""
        if key in self.cache:
            del self.cache[key]
    
    def clear(self) -> None:
        """清空缓存"""
        self.cache.clear()


class WVPAuthClient:
    """WVP认证客户端"""
    
    def __init__(self, base_url: str = "http://localhost:8080", username: str = "admin", password: str = "admin123"):
        self.base_url = base_url.rstrip('/')
        self.username = username
        self.password = password
        self.session = None
        self.token = None
        self.token_expires = None
        
        # 尝试多个可能的WVP端口
        self.wvp_urls = [
            "http://localhost:18080",  # 默认WVP端口
            "http://localhost:8080",   # 备用端口
            "http://127.0.0.1:18080",
            "http://127.0.0.1:8080",
            "http://localhost:28181",  # GB28181端口
            "http://127.0.0.1:28181"
        ]
    
    async def __aenter__(self):
        """异步上下文管理器入口"""
        self.session = aiohttp.ClientSession(
            timeout=aiohttp.ClientTimeout(total=30),
            headers={
                "Content-Type": "application/json",
                "Accept": "application/json",
                "User-Agent": "Campus-Twin-Python-Backend/1.0"
            }
        )
        
        # 查找活跃的WVP服务
        active_url = await self._find_active_wvp_service()
        if active_url:
            self.base_url = active_url
            await self._login()
        
        return self
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """异步上下文管理器出口"""
        if self.session:
            await self.session.close()
    
    async def _find_active_wvp_service(self) -> Optional[str]:
        """查找活跃的WVP服务"""
        logger.info("🔍 搜索活跃的Java后端WVP服务...")
        
        for url in self.wvp_urls:
            logger.debug(f"  尝试连接: {url}")
            try:
                # 尝试多个可能的API端点
                test_endpoints = [
                    "/api/device/query/devices",
                    "/device/query/devices", 
                    "/api/devices",
                    "/devices"
                ]
                
                for endpoint in test_endpoints:
                    try:
                        test_url = f"{url}{endpoint}?pageNum=1&pageSize=1"
                        
                        async with self.session.get(test_url) as response:
                            if response.status in [200, 401]:  # 200成功，401需要认证但服务存在
                                logger.info(f"  ✅ 找到活跃的WVP服务: {url}")
                                return url
                    except Exception:
                        continue
                        
            except Exception:
                continue
        
        logger.warning("❌ 未找到活跃的WVP服务")
        return None
    
    async def _login(self) -> bool:
        """登录获取token"""
        try:
            login_endpoints = [
                "/login",
                "/api/login", 
                "/auth/login"
            ]
            
            login_data = {
                "username": self.username,
                "password": self.password
            }
            
            for endpoint in login_endpoints:
                try:
                    login_url = f"{self.base_url}{endpoint}"
                    
                    async with self.session.post(login_url, json=login_data) as response:
                        if response.status == 200:
                            data = await response.json()
                            if data.get("code") == 200 or data.get("success"):
                                self.token = data.get("token") or data.get("data", {}).get("token")
                                self.token_expires = datetime.now() + timedelta(hours=24)
                                logger.info(f"✅ WVP登录成功")
                                return True
                except Exception:
                    continue
            
            logger.debug("WVP登录失败，可能不需要认证")
            return True  # 有些WVP服务不需要认证
            
        except Exception as e:
            logger.debug(f"WVP登录异常: {e}")
            return True  # 继续尝试，可能不需要认证
    
    async def _ensure_authenticated(self) -> bool:
        """确保已认证"""
        if not self.token:
            return True  # 可能不需要认证
        
        if self.token_expires and datetime.now() >= self.token_expires - timedelta(minutes=5):
            return await self._login()
        
        return True
    
    def _get_headers(self) -> Dict[str, str]:
        """获取请求头"""
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }
        if self.token:
            headers["Authorization"] = f"Bearer {self.token}"
        return headers
    
    async def _make_request(self, method: str, url: str, **kwargs) -> Dict[str, Any]:
        """发起认证请求"""
        await self._ensure_authenticated()
        headers = self._get_headers()
        
        try:
            async with self.session.request(method, f"{self.base_url}{url}", headers=headers, **kwargs) as response:
                if response.status == 401 and self.token:
                    # 尝试重新登录
                    if await self._login():
                        headers = self._get_headers()
                        async with self.session.request(method, f"{self.base_url}{url}", headers=headers, **kwargs) as retry_response:
                            if retry_response.status == 200:
                                return await retry_response.json()
                            else:
                                raise Exception(f"WVP请求失败: {retry_response.status}")
                    else:
                        raise Exception("WVP重新认证失败")
                elif response.status == 200:
                    return await response.json()
                else:
                    raise Exception(f"WVP请求失败: {response.status}")
        except Exception as e:
            logger.error(f"WVP请求异常: {e}")
            raise
    
    async def get_devices(self, page: int = 1, count: int = 50, **kwargs) -> Dict[str, Any]:
        """获取设备列表"""
        try:
            params = {
                "pageNum": page,
                "pageSize": count,
                **kwargs
            }
            
            # 尝试不同的设备查询端点
            device_endpoints = [
                "/api/device/query/devices",
                "/device/query/devices",
                "/api/devices",
                "/devices"
            ]
            
            for endpoint in device_endpoints:
                try:
                    data = await self._make_request("GET", endpoint, params=params)
                    logger.info(f"从 {endpoint} 获取设备列表成功，共 {data.get('total', 0)} 个设备")
                    return data
                except Exception as e:
                    logger.debug(f"端点 {endpoint} 失败: {e}")
                    continue
            
            raise Exception("所有设备端点都失败")
            
        except Exception as e:
            logger.error(f"获取设备列表失败: {e}")
            raise
    
    async def get_device_channels(self, device_id: str = None, page: int = 1, count: int = 50, **kwargs) -> Dict[str, Any]:
        """获取设备通道列表"""
        try:
            params = {
                "pageNum": page,
                "pageSize": count,
                **kwargs
            }
            
            if device_id:
                params["deviceId"] = device_id
            
            # 尝试不同的通道查询端点
            channel_endpoints = [
                "/api/device/query/devices/channels",
                "/device/query/devices/channels",
                f"/api/device/{device_id}/channels" if device_id else "/api/channels",
                f"/device/{device_id}/channels" if device_id else "/channels"
            ]
            
            for endpoint in channel_endpoints:
                try:
                    data = await self._make_request("GET", endpoint, params=params)
                    logger.info(f"从 {endpoint} 获取通道列表成功，共 {data.get('total', 0)} 个通道")
                    return data
                except Exception as e:
                    logger.debug(f"端点 {endpoint} 失败: {e}")
                    continue
            
            raise Exception("所有通道端点都失败")
            
        except Exception as e:
            logger.error(f"获取设备通道列表失败: {e}")
            raise
    
    async def get_play_url(self, device_id: str, channel_id: str) -> Dict[str, Any]:
        """获取播放URL"""
        try:
            # 尝试不同的播放URL端点
            play_endpoints = [
                f"/api/play/start/{device_id}/{channel_id}",
                f"/play/start/{device_id}/{channel_id}",
                f"/api/stream/start/{device_id}/{channel_id}",
                f"/stream/start/{device_id}/{channel_id}"
            ]
            
            for endpoint in play_endpoints:
                try:
                    data = await self._make_request("GET", endpoint)
                    logger.info(f"从 {endpoint} 获取播放URL成功: {device_id}/{channel_id}")
                    return data
                except Exception as e:
                    logger.debug(f"播放端点 {endpoint} 失败: {e}")
                    continue
            
            raise Exception("所有播放端点都失败")
            
        except Exception as e:
            logger.error(f"获取播放URL失败: {e}")
            raise
    
    async def stop_play(self, device_id: str, channel_id: str) -> Dict[str, Any]:
        """停止播放"""
        try:
            # 尝试不同的停止播放端点
            stop_endpoints = [
                f"/api/play/stop/{device_id}/{channel_id}",
                f"/play/stop/{device_id}/{channel_id}",
                f"/api/stream/stop/{device_id}/{channel_id}",
                f"/stream/stop/{device_id}/{channel_id}"
            ]
            
            for endpoint in stop_endpoints:
                try:
                    data = await self._make_request("GET", endpoint)
                    logger.info(f"从 {endpoint} 停止播放成功: {device_id}/{channel_id}")
                    return data
                except Exception as e:
                    logger.debug(f"停止端点 {endpoint} 失败: {e}")
                    continue
            
            raise Exception("所有停止端点都失败")
            
        except Exception as e:
            logger.error(f"停止播放失败: {e}")
            raise


class UnifiedWVPService:
    """统一的WVP服务类"""
    
    def __init__(self):
        self.cache_manager = CacheManager(default_ttl=300)  # 5分钟缓存
        self.play_url_cache = CacheManager(default_ttl=60)  # 播放URL缓存1分钟
        self.device_cache = CacheManager(default_ttl=180)   # 设备信息缓存3分钟
        
        # WVP配置
        self.wvp_config = {
            "base_url": "http://localhost:8080",
            "username": "admin",
            "password": "admin123"
        }
    
    def _get_play_format_priority(self) -> List[PlayFormat]:
        """获取播放格式优先级"""
        return [
            PlayFormat.WEBRTC,
            PlayFormat.HTTP_FLV,
            PlayFormat.HLS,
            PlayFormat.RTSP
        ]
    
    def _select_best_play_url(self, play_data: Dict[str, Any]) -> Dict[str, Any]:
        """选择最佳播放URL"""
        priority_formats = self._get_play_format_priority()
        
        # 格式映射
        format_mapping = {
            PlayFormat.WEBRTC: "rtc",
            PlayFormat.HTTP_FLV: "flv",
            PlayFormat.HLS: "hls",
            PlayFormat.RTSP: "rtsp"
        }
        
        selected_format = None
        selected_url = None
        
        # 按优先级选择可用的播放格式
        for format_type in priority_formats:
            url_key = format_mapping[format_type]
            if url_key in play_data and play_data[url_key]:
                selected_format = format_type.value
                selected_url = play_data[url_key]
                break
        
        # 如果没有找到优先格式，使用第一个可用的
        if not selected_url:
            for key, url in play_data.items():
                if url and key in format_mapping.values():
                    selected_format = key
                    selected_url = url
                    break
        
        return {
            "primary_format": selected_format,
            "primary_url": selected_url,
            "all_formats": play_data
        }
    
    async def get_cached_device_data(self, cache_key: str, fetch_func, ttl: int = 180) -> Any:
        """获取缓存的设备数据"""
        # 尝试从缓存获取
        cached_data = self.device_cache.get(cache_key)
        if cached_data is not None:
            logger.debug(f"从缓存获取数据: {cache_key}")
            return cached_data
        
        try:
            # 缓存未命中，从WVP获取数据
            data = await fetch_func()
            self.device_cache.set(cache_key, data, ttl)
            logger.debug(f"数据已缓存: {cache_key}")
            return data
        except Exception as e:
            logger.error(f"获取数据失败: {cache_key}, 错误: {e}")
            # 尝试返回过期的缓存数据作为降级策略
            expired_data = self.device_cache.cache.get(cache_key)
            if expired_data:
                logger.warning(f"使用过期缓存数据: {cache_key}")
                return expired_data[0]  # 返回数据部分，忽略过期时间
            raise
    
    async def get_camera_list(self, page: int = 1, count: int = 50, use_cache: bool = True, **kwargs) -> Dict[str, Any]:
        """
        获取摄像头列表（从Java后端WVP获取真实数据）
        
        Args:
            page: 页码
            count: 每页数量
            use_cache: 是否使用缓存
            **kwargs: 其他查询参数
            
        Returns:
            摄像头列表数据
        """
        cache_key = f"camera_list_{page}_{count}_{hash(str(sorted(kwargs.items())))}"
        
        if use_cache:
            cached_result = self.cache_manager.get(cache_key)
            if cached_result:
                logger.debug(f"从缓存返回摄像头列表: page={page}, count={count}")
                return cached_result
        
        try:
            # 使用认证客户端连接Java后端WVP
            async with WVPAuthClient(**self.wvp_config) as client:
                # 获取设备列表
                async def fetch_devices():
                    return await client.get_devices(page=page, count=count, **kwargs)
                
                devices_data = await self.get_cached_device_data(
                    f"devices_{page}_{count}", fetch_devices, ttl=180
                )
                
                # 获取所有设备的通道
                cameras = []
                total_channels = 0
                
                devices = devices_data.get("rows", [])
                
                for device in devices:
                    device_id = device.get("deviceId")
                    
                    try:
                        # 获取该设备的通道列表
                        async def fetch_device_channels():
                            return await client.get_device_channels(device_id=device_id, page=1, count=1000)
                        
                        channels_data = await self.get_cached_device_data(
                            f"channels_{device_id}", fetch_device_channels, ttl=180
                        )
                        
                        channels = channels_data.get("rows", [])
                        total_channels += len(channels)
                        
                        # 为每个通道创建摄像头记录
                        for channel in channels:
                            camera = {
                                "id": f"{device_id}_{channel.get('channelId', channel.get('deviceId', ''))}",
                                "name": channel.get("name", f"摄像头-{device.get('name', device_id)}"),
                                "device_id": device_id,
                                "channel_id": channel.get("channelId", channel.get("deviceId", "")),
                                "status": "online" if channel.get("status") == "ON" else "offline",
                                "manufacturer": device.get("manufacturer", ""),
                                "model": device.get("model", ""),
                                "ip_address": device.get("ip", ""),
                                "port": device.get("port", 5060),
                                "longitude": channel.get("longitude"),
                                "latitude": channel.get("latitude"),
                                "location": channel.get("address", device.get("address", "")),
                                "channel_type": channel.get("channelType", 0),
                                "sub_count": channel.get("subCount", 0),
                                "has_audio": channel.get("hasAudio", False),
                                "ptz_type": channel.get("ptzType", 0),
                                "stream_identification": channel.get("streamIdentification", ""),
                                "created_time": datetime.now().isoformat()
                            }
                            
                            cameras.append(camera)
                            
                    except Exception as e:
                        logger.warning(f"获取设备 {device_id} 的通道失败: {e}")
                        continue
            
            result = {
                "success": True,
                "data": {
                    "list": cameras,
                    "total": total_channels,
                    "page": page,
                    "count": count
                },
                "message": "从Java后端WVP获取摄像头列表成功"
            }
            
            # 缓存结果
            if use_cache:
                self.cache_manager.set(cache_key, result)
            
            logger.info(f"从Java后端WVP获取摄像头列表成功，共 {len(cameras)} 个摄像头")
            return result
            
        except Exception as e:
            logger.error(f"从Java后端WVP获取摄像头列表失败: {e}")
            return {
                "success": False,
                "data": None,
                "message": f"从Java后端WVP获取摄像头列表失败: {str(e)}"
            }
    
    async def get_camera_play_url(self, device_id: str, channel_id: str) -> Dict[str, Any]:
        """
        获取摄像头播放URL（从Java后端WVP获取）
        
        Args:
            device_id: 设备ID
            channel_id: 通道ID
            
        Returns:
            播放URL信息
        """
        try:
            # 使用认证客户端连接Java后端WVP
            async with WVPAuthClient(**self.wvp_config) as client:
                # 获取播放URL
                play_data = await client.get_play_url(device_id, channel_id)
            
            # 提取播放数据
            data = play_data.get("data", {})
            
            # 智能选择最佳播放URL
            best_play_info = self._select_best_play_url(data)
            
            result = {
                "success": True,
                "data": {
                    "device_id": device_id,
                    "channel_id": channel_id,
                    "primary_format": best_play_info.get("primary_format"),
                    "primary_url": best_play_info.get("primary_url"),
                    "all_formats": {
                        "flv": data.get("flv", ""),
                        "rtc": data.get("rtc", ""),
                        "rtmp": data.get("rtmp", ""),
                        "rtsp": data.get("rtsp", ""),
                        "ws_flv": data.get("ws_flv", ""),
                        "hls": data.get("hls", ""),
                        "https_flv": data.get("https_flv", ""),
                        "wss_flv": data.get("wss_flv", ""),
                        "fmp4": data.get("fmp4", ""),
                        "ts": data.get("ts", "")
                    },
                    "stream_id": data.get("stream", ""),
                    "media_server_id": data.get("mediaServerId", ""),
                    "media_info": data.get("mediaInfo", {})
                },
                "message": "从Java后端WVP获取播放URL成功"
            }
            
            logger.info(f"从Java后端WVP获取播放URL成功: {device_id}/{channel_id}")
            return result
            
        except Exception as e:
            logger.error(f"从Java后端WVP获取播放URL失败: {e}")
            return {
                "success": False,
                "data": None,
                "message": f"从Java后端WVP获取播放URL失败: {str(e)}"
            }
    
    async def stop_camera_play(self, device_id: str, channel_id: str) -> Dict[str, Any]:
        """
        停止摄像头播放（通过Java后端WVP）
        
        Args:
            device_id: 设备ID
            channel_id: 通道ID
            
        Returns:
            停止播放结果
        """
        try:
            # 使用认证客户端连接Java后端WVP
            async with WVPAuthClient(**self.wvp_config) as client:
                # 停止播放
                stop_data = await client.stop_play(device_id, channel_id)
            
            result = {
                "success": True,
                "data": stop_data,
                "message": "通过Java后端WVP停止播放成功"
            }
            
            logger.info(f"通过Java后端WVP停止播放成功: {device_id}/{channel_id}")
            return result
            
        except Exception as e:
            logger.error(f"通过Java后端WVP停止播放失败: {e}")
            return {
                "success": False,
                "data": None,
                "message": f"通过Java后端WVP停止播放失败: {str(e)}"
            }
    
    async def sync_wvp_devices_and_channels(self) -> Dict[str, Any]:
        """
        从Java后端WVP同步设备和通道数据到WVP数据表
        
        Returns:
            同步结果
        """
        try:
            db = get_database_manager()
            devices_synced = 0
            channels_synced = 0
            
            # 使用认证客户端连接Java后端WVP
            async with WVPAuthClient(**self.wvp_config) as client:
                # 获取设备列表
                devices_data = await client.get_devices(page=1, count=1000)
                devices = devices_data.get("rows", [])
                
                for device in devices:
                    device_id = device.get("deviceId")
                    if not device_id:
                        continue
                    
                    # 同步设备数据到wvp_devices表
                    device_query = """
                        INSERT OR REPLACE INTO wvp_devices (
                            device_id, device_name, manufacturer, model, firmware,
                            transport, stream_mode, ip, port, host_address, expires,
                            register_time, keepalive_time, channel_count, status,
                            updated_at
                        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
                    """
                    
                    db.execute_insert(device_query, (
                        device_id,
                        device.get("name", ""),
                        device.get("manufacturer", ""),
                        device.get("model", ""),
                        device.get("firmware", ""),
                        device.get("transport", "UDP"),
                        device.get("streamMode", "UDP"),
                        device.get("ip", ""),
                        device.get("port", 5060),
                        device.get("hostAddress", ""),
                        device.get("expires", 3600),
                        device.get("registerTime"),
                        device.get("keepaliveTime"),
                        0,  # 将在通道同步时更新
                        "online" if device.get("online") else "offline"
                    ))
                    devices_synced += 1
                    
                    # 获取该设备的通道列表
                    try:
                        channels_data = await client.get_device_channels(device_id=device_id, page=1, count=1000)
                        channels = channels_data.get("rows", [])
                        
                        # 更新设备的通道数量
                        db.execute_update(
                            "UPDATE wvp_devices SET channel_count = ? WHERE device_id = ?",
                            (len(channels), device_id)
                        )
                        
                        for channel in channels:
                            channel_id = channel.get("channelId", channel.get("deviceId", ""))
                            
                            # 同步通道数据到wvp_channels表
                            channel_query = """
                                INSERT OR REPLACE INTO wvp_channels (
                                    device_id, channel_id, channel_name, manufacturer, model,
                                    owner, civil_code, block, address, parental, parent_id,
                                    safety_way, register_way, cert_num, certifiable, err_code,
                                    end_time, secrecy, ip_address, port, password, ptz_type,
                                    status, longitude, latitude, updated_at
                                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
                            """
                            
                            db.execute_insert(channel_query, (
                                device_id,
                                channel_id,
                                channel.get("name", ""),
                                channel.get("manufacturer", ""),
                                channel.get("model", ""),
                                channel.get("owner", ""),
                                channel.get("civilCode", ""),
                                channel.get("block", ""),
                                channel.get("address", ""),
                                channel.get("parental", 0),
                                channel.get("parentId", ""),
                                channel.get("safetyWay", 0),
                                channel.get("registerWay", 1),
                                channel.get("certNum", ""),
                                channel.get("certifiable", 0),
                                channel.get("errCode", 0),
                                channel.get("endTime"),
                                channel.get("secrecy", ""),
                                channel.get("ipAddress", ""),
                                channel.get("port", 0),
                                channel.get("password", ""),
                                channel.get("ptzType", 0),
                                "online" if channel.get("status") == "ON" else "offline",
                                float(channel.get("longitude") or 0.0),
                                float(channel.get("latitude") or 0.0)
                            ))
                            channels_synced += 1
                            
                    except Exception as e:
                        logger.warning(f"同步设备 {device_id} 的通道失败: {e}")
                        continue
            
            result = {
                "success": True,
                "data": {
                    "devices_synced": devices_synced,
                    "channels_synced": channels_synced
                },
                "message": f"WVP数据同步完成，设备: {devices_synced}个，通道: {channels_synced}个"
            }
            
            logger.info(f"WVP数据同步完成: {result['message']}")
            return result
            
        except Exception as e:
            logger.error(f"WVP数据同步失败: {e}")
            return {
                "success": False,
                "data": None,
                "message": f"WVP数据同步失败: {str(e)}"
            }

    async def sync_cameras_from_wvp(self) -> Dict[str, Any]:
        """
        从Java后端WVP同步摄像头数据到本地数据库
        
        Returns:
            同步结果
        """
        try:
            # 首先同步WVP设备和通道数据
            wvp_sync_result = await self.sync_wvp_devices_and_channels()
            if not wvp_sync_result["success"]:
                return wvp_sync_result
            
            # 获取Java后端WVP中的摄像头列表
            wvp_cameras = await self.get_camera_list(page=1, count=1000)
            
            if not wvp_cameras["success"]:
                return wvp_cameras
            
            cameras_data = wvp_cameras["data"]["list"]
            
            db = get_database_manager()
            synced_count = 0
            updated_count = 0
            
            for camera_data in cameras_data:
                device_id = camera_data["device_id"]
                channel_id = camera_data["channel_id"]
                
                # 查找现有摄像头
                existing_camera = db.get_camera_by_wvp_device(device_id, channel_id)
                
                if existing_camera:
                    # 更新现有摄像头 - 检查名称冲突
                    new_name = camera_data["name"]
                    existing_name_camera = db.get_camera_by_name(new_name)
                    
                    # 如果名称冲突且不是同一个摄像头，则生成唯一名称
                    if existing_name_camera and existing_name_camera["id"] != existing_camera["id"]:
                        base_name = new_name
                        counter = 1
                        while True:
                            unique_name = f"{base_name}_{counter}"
                            if not db.get_camera_by_name(unique_name):
                                new_name = unique_name
                                break
                            counter += 1
                    
                    # 生成正确的RTSP URL（如果当前为空）
                    current_rtsp = existing_camera.get('rtsp_url')
                    rtsp_url = current_rtsp
                    if not current_rtsp:
                        rtsp_url = f"rtsp://localhost:554/rtp/{device_id}_{channel_id}"
                        logger.info(f"✅ 更新摄像头 {existing_camera['id']} 的RTSP URL: {rtsp_url}")
                    
                    update_query = """
                        UPDATE cameras SET 
                            name = ?, status = ?, location = ?, longitude = ?, latitude = ?, rtsp_url = ?,
                            updated_at = CURRENT_TIMESTAMP
                        WHERE wvp_device_id = ? AND wvp_channel_id = ?
                    """
                    # 确保longitude和latitude不为None
                    longitude = camera_data.get("longitude")
                    latitude = camera_data.get("latitude")
                    if longitude is None:
                        longitude = 0.0
                    if latitude is None:
                        latitude = 0.0
                    
                    db.execute_update(update_query, (
                        new_name, camera_data["status"], camera_data["location"],
                        float(longitude or 0.0), float(latitude or 0.0), rtsp_url, device_id, channel_id
                    ))
                    updated_count += 1
                else:
                    # 创建新摄像头 - 处理重复名称
                    base_name = camera_data["name"]
                    unique_name = base_name
                    counter = 1
                    
                    # 检查名称是否已存在，如果存在则添加后缀
                    while db.get_camera_by_name(unique_name):
                        unique_name = f"{base_name}_{counter}"
                        counter += 1
                    
                    # 生成正确的RTSP URL
                    rtsp_url = f"rtsp://localhost:554/rtp/{device_id}_{channel_id}"
                    
                    insert_query = """
                        INSERT INTO cameras (
                            name, wvp_device_id, wvp_channel_id, status, location,
                            longitude, latitude, ai_enabled, rtsp_url, created_at
                        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
                    """
                    # 确保longitude和latitude不为None
                    longitude = camera_data.get("longitude")
                    latitude = camera_data.get("latitude")
                    if longitude is None:
                        longitude = 0.0
                    if latitude is None:
                        latitude = 0.0
                    
                    db.execute_insert(insert_query, (
                        unique_name, device_id, channel_id, camera_data["status"],
                        camera_data["location"], float(longitude or 0.0), float(latitude or 0.0), True, rtsp_url
                    ))
                    
                    logger.info(f"✅ 同步创建摄像头: {unique_name}, RTSP: {rtsp_url}")
                    synced_count += 1
            
            result = {
                "success": True,
                "data": {
                    "total_cameras": len(cameras_data),
                    "synced_count": synced_count,
                    "updated_count": updated_count
                },
                "message": f"从Java后端WVP同步完成，新增 {synced_count} 个，更新 {updated_count} 个摄像头"
            }
            
            logger.info(f"从Java后端WVP同步摄像头数据完成: {result['message']}")
            return result
            
        except Exception as e:
            logger.error(f"从Java后端WVP同步摄像头数据失败: {e}")
            return {
                "success": False,
                "data": None,
                "message": f"从Java后端WVP同步失败: {str(e)}"
            }
    
    async def test_wvp_connection(self) -> Dict[str, Any]:
        """
        测试Java后端WVP连接
        
        Returns:
            连接测试结果
        """
        try:
            # 使用认证客户端测试连接
            async with WVPAuthClient(**self.wvp_config) as client:
                # 尝试获取设备列表来测试连接
                data = await client.get_devices(page=1, count=1)
            
            result = {
                "success": True,
                "data": {
                    "server_url": client.base_url,
                    "total_devices": data.get("total", 0),
                    "connection_time": datetime.now().isoformat()
                },
                "message": "Java后端WVP连接测试成功"
            }
            
            logger.info(f"Java后端WVP连接测试成功: {client.base_url}")
            return result
            
        except Exception as e:
            logger.error(f"Java后端WVP连接测试失败: {e}")
            return {
                "success": False,
                "data": None,
                "message": f"Java后端WVP连接测试失败: {str(e)}"
            }


# 全局统一WVP服务实例
unified_wvp_service = UnifiedWVPService()


def get_unified_wvp_service() -> UnifiedWVPService:
    """获取统一WVP服务实例"""
    return unified_wvp_service


# 兼容性函数，保持与原始接口一致
def get_wvp_service() -> UnifiedWVPService:
    """获取WVP服务实例（兼容性函数）"""
    return unified_wvp_service